using System;
using Microsoft.SPOT;

namespace MicroSnake
{
    class Snake
    {
        private short MAX_LENGTH = 400;

        private Direction direction;

        // Snake coordinates handled with a circular buffer
        private short[] posX;
        private short[] posY;
        private short head;
        private short tail;

        private GameBoard gameBoard;

        public Snake(GameBoard gameBoard, short startY, short startX, short length)
        {
            this.gameBoard = gameBoard;

            posX = new short[MAX_LENGTH];
            posY = new short[MAX_LENGTH];
            tail = 0;
            head = (short)(length - 1);
            direction = Direction.Right;

            for(short i=0; i<length; i++)
            {
                posX[i] = (short)(startX + i);
                posY[i] = startY;
                gameBoard.Items[posX[i]][posY[i]] = GameItems.Tail;
            }

            gameBoard.Items[posX[head]][posY[head]] = GameItems.HeadRight;
        }

        /// <summary>
        /// Move the snake toward the current direction
        /// </summary>
        public void Update()
        {
            short nextHead = (short)((head + 1) % 20);
            short nextTail = (short)((tail + 1) % 20);

            switch (direction)
            {
                case Direction.Up:
                    posX[nextHead] = posX[head];
                    posY[nextHead] = (short)(posY[head] - 1);

                    if (posY[nextHead] < 0)
                    {
                        posY[nextHead] = 19;
                    }

                    gameBoard.Items[posX[nextHead]][posY[nextHead]] = GameItems.HeadUp;
                    break;

                case Direction.Down:
                    posX[nextHead] = posX[head];
                    posY[nextHead] = (short)((posY[head] + 1) % 20);

                    gameBoard.Items[posX[nextHead]][posY[nextHead]] = GameItems.HeadDown;                    
                    break;

                case Direction.Left:
                    posX[nextHead] = (short)(posX[head] - 1);
                    posY[nextHead] = posY[head];

                    if (posX[nextHead] < 0)
                    {
                        posX[nextHead] = 19;
                    }

                    gameBoard.Items[posX[nextHead]][posY[nextHead]] = GameItems.HeadLeft;
                    break;

                case Direction.Right:
                    posX[nextHead] = (short)((posX[head] + 1) % 20);
                    posY[nextHead] = posY[head];

                    gameBoard.Items[posX[nextHead]][posY[nextHead]] = GameItems.HeadRight;
                    break;
            }

            gameBoard.Items[posX[tail]][posY[tail]] = GameItems.Empty;
            gameBoard.Items[posX[head]][posY[head]] = GameItems.Tail;

            head = nextHead;
            tail = nextTail;
        }

        /// <summary>
        /// Change the snake direction
        /// </summary>
        public void ChangeDirection(Direction nextDirection)
        {
            if (direction == Direction.Up && nextDirection == Direction.Down)
            {
                return;
            }

            if (direction == Direction.Down && nextDirection == Direction.Up)
            {
                return;
            }

            if (direction == Direction.Left && nextDirection == Direction.Right)
            {
                return;
            }

            if (direction == Direction.Right && nextDirection == Direction.Left)
            {
                return;
            }
            
            direction = nextDirection;            
        }
    }
}
